package com.mazaiting.instructions.math;

import com.mazaiting.instructions.base.NoOperandsInstruction;
import com.mazaiting.rtda.MtFrame;
import com.mazaiting.rtda.MtOperandStack;

/**
 * 求余指令
 *
 * @author mazaiting
 * @since 2021/8/14
 */
public class RemInstruction {

    /**
     * 双精度浮点 求余
     */
    public static class DRem extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            double v1 = stack.popDouble();
            double v2 = stack.popDouble();
            if (v2 == 0D) {
                throw new RuntimeException("java.lang.ArithmeticException: / by zero");
            }
            double result = v1 % v2;
            stack.pushDouble(result);
        }
    }

    /**
     * 单精度浮点 求余
     */
    public static class FRem extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            float v1 = stack.popFloat();
            float v2 = stack.popFloat();
            if (v2 == 0F) {
                throw new RuntimeException("java.lang.ArithmeticException: / by zero");
            }
            float result = v1 % v2;
            stack.pushFloat(result);
        }
    }

    /**
     * 整型 求余
     */
    public static class IRem extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            int v1 = stack.popInt();
            int v2 = stack.popInt();
            if (v2 == 0) {
                throw new RuntimeException("java.lang.ArithmeticException: / by zero");
            }
            int result = v1 % v2;
            stack.pushInt(result);
        }
    }

    /**
     * 长整型 求余
     */
    public static class LRem extends NoOperandsInstruction {
        @Override
        public void execute(MtFrame frame) {
            MtOperandStack stack = frame.getOperandStack();
            long v1 = stack.popLong();
            long v2 = stack.popLong();
            if (v2 == 0L) {
                throw new RuntimeException("java.lang.ArithmeticException: / by zero");
            }
            long result = v1 % v2;
            stack.pushLong(result);
        }
    }
}
